package com.yunxin.core.application.service.impl;

import com.yunxin.common.exception.BusinessException;
import com.yunxin.common.result.ResultCode;
import com.yunxin.common.utils.JacksonUtils;
import com.yunxin.common.utils.SnowflakeKeyGenerator;
import com.yunxin.core.application.assembler.PageAssembler;
import com.yunxin.core.application.command.page.AddPageCommand;
import com.yunxin.core.application.command.page.PageConfigInfoCommand;
import com.yunxin.core.application.command.page.PageInfoDataCommand;
import com.yunxin.core.application.command.page.UpdatePageCommand;
import com.yunxin.core.application.service.PageApplicationAdminService;
import com.yunxin.core.domain.model.page.Page;
import com.yunxin.core.domain.model.page.PageCache;
import com.yunxin.core.domain.model.page.PageCacheRepository;
import com.yunxin.core.domain.model.page.PageRepository;
import com.yunxin.core.infra.common.page.enums.PgeCacheStatusEnum;
import com.yunxin.core.utils.infra.common.enums.KeyGeneratorPrefixEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author zero°
 * @since 2023-05-27
 */
@Service
@RequiredArgsConstructor
public class PageApplicationAdminServiceImpl implements PageApplicationAdminService {

    private final PageRepository pageRepository;

    private final PageCacheRepository pageCacheRepository;

    private final PageAssembler pageAssembler;

    private final SnowflakeKeyGenerator sequenceGenerator;

    @Override
    public boolean addPage(AddPageCommand command) {
        Page page = pageAssembler.fromAddPageCommand(command);
        page.setPageCode(sequenceGenerator.generateKey(KeyGeneratorPrefixEnum.PAGE.getPrefix()));
        return pageRepository.savePage(page);
    }

    @Override
    public boolean updatePage(UpdatePageCommand command) {
        Page oldPage = pageRepository.getPageById(command.getId());
        if (Objects.isNull(oldPage)) {
            throw new BusinessException(ResultCode.DATA_NO_EXIST_ERROR);
        }
        Page page = pageAssembler.fromUpdatePageCommand(command);
        page.setVersion(oldPage.getVersion() + 1);
        return pageRepository.updatePage(page);

    }

    @Override
    public boolean savePageConfig(PageConfigInfoCommand command) {
        return addPageCache(command, PgeCacheStatusEnum.UNPUBLISHED.getValue());
    }

    @Override
    public boolean releasePageConfig(PageConfigInfoCommand command) {
        return addPageCache(command, PgeCacheStatusEnum.PUBLISHED.getValue());
    }

    /**
     * 保存页面缓存数据
     *
     * @param command       command
     * @param releaseStatus releaseStatus
     * @return boolean
     */
    private boolean addPageCache(PageConfigInfoCommand command, int releaseStatus) {
        PageCache pageCache = new PageCache();
        setElementCode(command.getPageConfig());
        pageCache.setPageCode(command.getPageCode());
        pageCache.setPageData(JacksonUtils.X.format(command.getPageConfig()));
        pageCache.setReleaseStatus(releaseStatus);
        pageCache.setCreator(command.getCreator());
        return pageCacheRepository.savePageCache(pageCache);
    }

    /**
     * 设置元素code
     *
     * @param pageConfig pageConfig
     */
    private void setElementCode(PageInfoDataCommand pageConfig) {
        if (Objects.nonNull(pageConfig)) {
            pageConfig.getComponentData().forEach(x -> x.getPageSubComponent().forEach(y -> y.getPageComponentElement().forEach(z -> {
                        if (StringUtils.isBlank(z.getElementCode())) {
                            z.setElementCode(sequenceGenerator.generateKey(KeyGeneratorPrefixEnum.ELEMENT_CODE.getPrefix()));
                        }
                    })
            ));
        }
    }

}
